package com.aiyige.page.publish.selecttag;

import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.Editable;
import android.text.InputFilter;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.aiyige.R;
import com.aiyige.arouter.config.ARouterConfig;
import com.aiyige.base.api.ApiManager;
import com.aiyige.base.api.ResponseCode;
import com.aiyige.model.tag.Tag;
import com.aiyige.model.tag.TagPopular;
import com.aiyige.model.tag.UserTagRecord;
import com.aiyige.model.task.Task;
import com.aiyige.page.publish.selecttag.adapter.SelectTagAdapter;
import com.aiyige.page.publish.selecttag.adapter.SelectTagSearchAdapter;
import com.aiyige.page.publish.selecttag.model.SelectTagItem;
import com.aiyige.setup.util.SetupUtil;
import com.aiyige.utils.ErrorUtil;
import com.aiyige.utils.ExcludeEmojiInputFilter;
import com.aiyige.utils.InputNumFilter;
import com.aiyige.utils.ListUtil;
import com.aiyige.utils.RetrofitUtil;
import com.aiyige.utils.ToastX;
import com.aiyige.utils.ValidateUtil;
import com.aiyige.utils.dialog.LoadingDialog;
import com.alibaba.android.arouter.facade.annotation.Autowired;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.alibaba.android.arouter.launcher.ARouter;
import com.alibaba.fastjson.JSON;
import com.beloo.widget.chipslayoutmanager.ChipsLayoutManager;
import com.chad.library.adapter.base.BaseQuickAdapter;

import java.util.LinkedList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import okhttp3.ResponseBody;
import retrofit2.Response;
import timber.log.Timber;


@Route(path = ARouterConfig.SelectTagPage)
public class SelectTagPage extends AppCompatActivity {
    public static final String TAG = SelectTagPage.class.getSimpleName();
    public static final String EXTRA_KEY_SELECTED_TAG_ID = "com.aiyige.extra.EXTRA_KEY_SELECT_TAG_ID";
    public static final String EXTRA_KEY_SELECTED_TAG_NAME = "com.aiyige.extra.EXTRA_KEY_SELECT_TAG_NAME";
    public static final int HANDLE_SEARCH = 1;
    public static final int MAX_INPUT_NUM = 15;
    @BindView(R.id.backBtn)
    ImageView backBtn;
    @BindView(R.id.searchIcon)
    ImageView searchIcon;
    @BindView(R.id.inputEt)
    EditText inputEt;
    @BindView(R.id.searchBox)
    FrameLayout searchBox;
    @BindView(R.id.cancelSearchBtn)
    Button cancelSearchBtn;
    @BindView(R.id.deleteHistoryTagBtn)
    ImageView deleteHistoryTagBtn;
    @BindView(R.id.historyTagRv)
    RecyclerView historyTagRv;
    @BindView(R.id.historyTagLayout)
    LinearLayout historyTagLayout;
    @BindView(R.id.hotTagRv)
    RecyclerView hotTagRv;
    @BindView(R.id.hotTagLayout)
    LinearLayout hotTagLayout;
    @BindView(R.id.searchResultRv)
    RecyclerView searchResultRv;
    @BindView(R.id.searchResultLayout)
    FrameLayout searchResultLayout;
    SelectTagAdapter historyTagAdapter;
    SelectTagAdapter hotTagAdapter;
    Handler mainHandler;
    Handler searchHandler;
    HandlerThread searchThread;
    SelectTagSearchAdapter selectTagSearchAdapter;
    @Autowired
    String[] selectedIds = {};

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.page_select_tag);
        ButterKnife.bind(this);
        ARouter.getInstance().inject(this);
        searchThread = new HandlerThread(TAG + "SearchThread");
        searchThread.start();
        mainHandler = new Handler(Looper.getMainLooper());
        searchHandler = new Handler(searchThread.getLooper()) {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case HANDLE_SEARCH:
                        String searchStr = (String) msg.obj;
                        final List<SelectTagItem> selectTagItemList = new LinkedList<>();
                        if (!TextUtils.isEmpty(searchStr)) {
                            try {
                                Response<ResponseBody> response = ApiManager.getService()
                                        .getHintTag(SetupUtil.GROUP_TYPE_OTHER, searchStr)
                                        .execute();
                                if (response.code() != ResponseCode.OK) {
                                    throw new Exception(ErrorUtil.extractMessageFromErrorResponse(response));
                                }
                                String json = RetrofitUtil.getResponseBodyAsString(response);
                                List<Tag> tagList = JSON.parseArray(json, Tag.class);
                                for (Tag tag : tagList) {
                                    selectTagItemList.add(SelectTagItem.newBuilder()
                                            .id(tag.getId())
                                            .name(tag.getName())
                                            .build());
                                }
                            } catch (Exception e) {
                                Timber.e("handleMessage:" + Log.getStackTraceString(e));
                            }
                        }
                        mainHandler.post(new Runnable() {
                            @Override
                            public void run() {
                                selectTagSearchAdapter.setNewData(selectTagItemList);
                            }
                        });
                        break;
                    default:
                        break;
                }
            }
        };
        historyTagRv.setLayoutManager(ChipsLayoutManager.newBuilder(this)
                .setOrientation(ChipsLayoutManager.HORIZONTAL)
                .build());
        hotTagRv.setLayoutManager(ChipsLayoutManager.newBuilder(this)
                .setOrientation(ChipsLayoutManager.HORIZONTAL)
                .build());
        searchResultRv.setLayoutManager(new LinearLayoutManager(this));
        selectTagSearchAdapter = new SelectTagSearchAdapter();
        selectTagSearchAdapter.bindToRecyclerView(searchResultRv);
        historyTagAdapter = new SelectTagAdapter();
        hotTagAdapter = new SelectTagAdapter();
        historyTagAdapter.bindToRecyclerView(historyTagRv);
        hotTagAdapter.bindToRecyclerView(hotTagRv);
        historyTagAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                doSelectTag(historyTagAdapter.getItem(position));
            }
        });


        hotTagAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                doSelectTag(hotTagAdapter.getItem(position));
            }
        });

        selectTagSearchAdapter.setOnItemClickListener(new BaseQuickAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(BaseQuickAdapter adapter, View view, int position) {
                doSelectTag(selectTagSearchAdapter.getItem(position));
            }
        });

        InputNumFilter inputNumFilter = new InputNumFilter(MAX_INPUT_NUM);
        inputEt.setFilters(new InputFilter[]{new ExcludeEmojiInputFilter(), inputNumFilter});
        inputEt.addTextChangedListener(new TextWatcher() {
            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {

            }

            @Override
            public void afterTextChanged(Editable s) {
                if (s.length() != 0) {
                    searchResultLayout.setVisibility(View.VISIBLE);
                }
                doSearch(s.toString().trim());
            }
        });

        inputEt.setOnEditorActionListener(new TextView.OnEditorActionListener() {
            @Override
            public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
                if (actionId == EditorInfo.IME_ACTION_DONE) {
                    if (!TextUtils.isEmpty(v.getText().toString().trim())) {
                        if (ValidateUtil.checkTagName(v.getText().toString().trim())) {
                            doAddTag(v.getText().toString().trim());
                        } else {
                            ToastX.show(R.string.tag_name_only_support_chinese_or_english);
                        }
                    }
                    return true;
                }
                return false;
            }
        });
        requestData();
    }

    private void doSearch(String searchStr) {
        Message msg = Message.obtain();
        msg.what = HANDLE_SEARCH;
        msg.obj = searchStr;
        searchHandler.removeMessages(HANDLE_SEARCH);
        searchHandler.sendMessage(msg);
    }

    public void requestData() {
        new RequestDataTask().execute(SetupUtil.GROUP_TYPE_OTHER);
    }

    public void doAddTag(String tagName) {
        new CreateUserTagTask().execute(tagName, SetupUtil.CHANNEL_ALL, SetupUtil.GROUP_TYPE_OTHER);
    }


    public void doSelectTag(SelectTagItem item) {
        for (int i = 0; i < selectedIds.length; ++i) {
            if (selectedIds[i].equals(item.getId())) {
                ToastX.show(R.string.tag_has_selectd);
                return;
            }
        }
        Intent intent = new Intent();
        intent.putExtra(EXTRA_KEY_SELECTED_TAG_NAME, item.getName());
        intent.putExtra(EXTRA_KEY_SELECTED_TAG_ID, item.getId());
        setResult(RESULT_OK, intent);
        finish();
    }

    public void doDeleteHistoryTag() {
        new DeleteHistoryTagTask().execute();
    }

    @OnClick({R.id.backBtn, R.id.cancelSearchBtn, R.id.deleteHistoryTagBtn})
    public void onViewClicked(View view) {
        switch (view.getId()) {
            case R.id.backBtn:
                setResult(RESULT_CANCELED);
                finish();
                break;
            case R.id.cancelSearchBtn:
                if (searchResultLayout.getVisibility() == View.VISIBLE) {
                    inputEt.setText("");
                    inputEt.clearFocus();
                    searchResultLayout.setVisibility(View.INVISIBLE);
                } else {
                    setResult(RESULT_CANCELED);
                    finish();
                }
                break;
            case R.id.deleteHistoryTagBtn:
                doDeleteHistoryTag();
                break;
        }
    }

    public class RequestDataTask extends AsyncTask<String, Object, Object> {
        LoadingDialog loadingDialog;
        String groupType;
        List<SelectTagItem> historyTagList = new LinkedList<SelectTagItem>();
        List<SelectTagItem> hotTagList = new LinkedList<SelectTagItem>();

        @Override
        protected void onPreExecute() {
            loadingDialog = LoadingDialog.newBuilder()
                    .with(SelectTagPage.this)
                    .show();
        }

        @Override
        protected Object doInBackground(String... params) {
            groupType = params[0];
            try {
                Response<ResponseBody> response = ApiManager.getService()
                        .getHistoryTag(groupType)
                        .execute();
                if (response.code() != ResponseCode.OK) {
                    throw new Exception(ErrorUtil.extractMessageFromErrorResponse(response));
                } else {
                    String json = RetrofitUtil.getResponseBodyAsString(response);
                    List<UserTagRecord> userTagRecordList = JSON.parseArray(json, UserTagRecord.class);
                    for (UserTagRecord record : userTagRecordList) {
                        historyTagList.add(SelectTagItem.newBuilder()
                                .id(record.getTagId())
                                .name(record.getTagName())
                                .build());
                    }
                }
                response = ApiManager.getService()
                        .getPopularTag(groupType)
                        .execute();
                if (response.code() != ResponseCode.OK) {
                    throw new Exception(ErrorUtil.extractMessageFromErrorResponse(response));
                } else {
                    String json = RetrofitUtil.getResponseBodyAsString(response);
                    List<TagPopular> tagPopularList = JSON.parseArray(json, TagPopular.class);
                    for (TagPopular tagPopular : tagPopularList) {
                        hotTagList.add(SelectTagItem.newBuilder()
                                .id(tagPopular.getId())
                                .name(tagPopular.getName())
                                .build());
                    }
                }
                return null;
            } catch (Exception e) {
                return e;
            }
        }

        @Override
        protected void onPostExecute(Object o) {
            loadingDialog.dismiss();
            if (o instanceof Exception) {
                hotTagList.clear();
                historyTagList.clear();
                ToastX.show(((Exception) o).getMessage());
            } else {
                if (!ListUtil.isEmpty(historyTagList)) {
                    historyTagLayout.setVisibility(View.VISIBLE);
                    historyTagAdapter.setNewData(historyTagList);
                }

                if (!ListUtil.isEmpty(hotTagList)) {
                    hotTagLayout.setVisibility(View.VISIBLE);
                    hotTagAdapter.setNewData(hotTagList);
                }
            }
        }
    }

    public class DeleteHistoryTagTask extends AsyncTask<Object, Object, Object> {
        LoadingDialog loadingDialog;

        @Override
        protected void onPreExecute() {
            loadingDialog = LoadingDialog.newBuilder()
                    .with(SelectTagPage.this)
                    .message(R.string.text_process)
                    .show();
        }

        @Override
        protected Object doInBackground(Object... objects) {
            try {
                Response<ResponseBody> response = ApiManager.getService()
                        .createTask(Task.newBuilder()
                                .name(Task.batchDeleteAllUserTagRecords)
                                .build())
                        .execute();
                if (response.code() != ResponseCode.CREATED) {
                    throw new Exception(ErrorUtil.extractMessageFromErrorResponse(response));
                }
                return null;
            } catch (Exception e) {
                return e;
            }
        }

        @Override
        protected void onPostExecute(Object o) {
            loadingDialog.dismiss();
            if (o instanceof Exception) {
                ToastX.show(((Exception) o).getMessage());
            } else {
                historyTagLayout.setVisibility(View.GONE);
            }
        }
    }

    public class CreateUserTagTask extends AsyncTask<String, Object, Object> {
        LoadingDialog loadingDialog;
        String tagName;
        String channel;
        String groupType;

        @Override
        protected void onPreExecute() {
            loadingDialog = LoadingDialog.newBuilder()
                    .with(SelectTagPage.this)
                    .message(R.string.text_process)
                    .show();
        }

        @Override
        protected Object doInBackground(String... strings) {
            tagName = strings[0];
            channel = strings[1];
            groupType = strings[2];
            try {
                Response<ResponseBody> response = ApiManager.getService().createUserTag(Tag.newBuilder()
                        .name(tagName)
                        .channel(channel)
                        .groupType(groupType)
                        .build())
                        .execute();
                if (response.code() != ResponseCode.CREATED) {
                    throw new Exception(ErrorUtil.extractMessageFromErrorResponse(response));
                } else {
                    String json = RetrofitUtil.getResponseBodyAsString(response);
                    Tag tag = JSON.parseObject(json, Tag.class);
                    return SelectTagItem.newBuilder()
                            .id(tag.getId())
                            .name(tag.getName())
                            .build();
                }
            } catch (Exception e) {
                return e;
            }
        }

        @Override
        protected void onPostExecute(Object o) {
            loadingDialog.dismiss();
            if (o instanceof SelectTagItem) {
                doSelectTag((SelectTagItem) o);
            } else if (o instanceof Exception) {
                ToastX.show(((Exception) o).getMessage());
            } else {
                ToastX.show(R.string.add_tag_failed);
            }
        }
    }

    @Override
    protected void onDestroy() {
        searchThread.quit();
        super.onDestroy();
    }
}
